iT邦幫忙

5

[jQuery note.] queue 簡單應用心得

  • 分享至 

  • xImage
  •  

之前工作的時候,為了要在畫面上加入一些動態效果,並且讓他循序自動執行。所以有這方考量:

1.使用 setTimeout 或是 setInterval
2.利用 animate 可以延遲的方式重新呼叫
3.使用 queue
首先我嘗試了第一個方法,將要執行的東西,包成 function,然後利用 setTimeout 或是 setInterval 呼叫。很好,他可以運作了,但是我遇到另一個問題,當我需要中斷他,或是暫停的時候,用這種方式呼叫就相對的麻煩。因為我加入了動態(Effect)的效果,如果直接強制中斷,那該怎麼知道他做到 function 中的哪一段呢?

後來我換了第二個方法,使用 animate 就可以延遲,也可以利用 callback 回呼自己,更有 stop() 可用。那,第二個問題來了,當我 stop() 之後,需要重新開始時,只能重新呼叫一次那個 callback 並把整個程序全部重做一次。如果沒有其他的事件時,他是可以很順利的走完,但倘若參雜了其他的事件,那就會有干擾的狀況發生。其實所謂干擾的狀況,並不是 API 本身的問題,我相信那是可以人為控制的,就是我寫的太爛才會發生干擾的意思啦。

後來我在 API 中找到了 queue 這個東西。先來簡單介紹一下他是做甚麼用的。他的作用是將你要執行的 function 丟到陣列裡面去依序執行。舉個簡單的例子,倘若我們要做一個動態效果:

$('#div-a').animate({ left: "+=20" }, 1000, function() {
    $('#div-a').animate({ top: "+=30" }, 1000, function() {
        $('#div-a').animate({ left: "+=50" }, 1000, function() {
            alert('動態效果結束了');
        });
    });
});

這種東西如果一多起來,跟噩夢沒兩樣。如果使用 queue 來做的話,那麼我可以改寫成這樣:

var myAnimate = function() {
    $('#div-a').animate({ left: "+=20"}, 1000).queue(function() { $(this).dequeue(); } );
    $('#div-a').animate({ top: "+=30"}, 1000).queue(function() { $(this).dequeue(); } );
    $('#div-a').animate({ left: "+=50"}, 1000).queue(function() { alert('動態效果結束了'); } );
};
 
myAnimate();

這樣就可以了。如果要讓他循序,就把最後一個 alert 換成 myAnimate(); 就可以達到循序。其實 queue 可以把他看做是一個陣列,而 dequeue 則是呼叫陣列中下一個元件出來執行。

// 將要循序執行的程序寫成陣列
var FUNC = [
    // animate 結束的 callback 再次呼叫 myAnimate,等於告訴他,請執行下一個 queue 元件
    function() { $('#div-a').animate({ left: "+=20"}, 1000, myAnimate); },
    function() { $('#div-a').animate({ top: "+=30"}, 1000, myAnimate); },
    function() { $('#div-a').animate({ left: "+=50"}, 1000, myAnimate); },
    function() { alert('動態效果結束了'); }
];
 
// 將 dequeue 指定給變數 myAnimate 並包裝成 function
var myAnimate = function() {
    $('#div-a').dequeue("myAnimation");
}
 
// 把 FUNC 這個陣列指定給名稱為 myAnimation
$('#div-a').queue("myAnimation", FUNC);
 
// 呼叫 myAnimate,由於呼叫了 dequeue,他便會開始從 myAnimation 的第一個程序開始執行
myAnimate();

這樣就是 queue 的做法,更詳盡的資料可以查看 jQuery 的未壓縮格式關於 queue 的部分。

再來,在 jQuery 1.4 中,新加入了一個新的方法 .clearQueue,他的作用是用於清除(或是取消)所有從 queue 中所加入的任何 function,換句話說,如果你在 queue 的 callback 中有使用任何程序的話,是可以使用 clearQueue 把他強制給取消的。

另外,官方有說他可以停止 fx 相關的動態效果,類似於使用 stop() 的效果,但是我是用過的之後覺得,動態效果還是用 stop() 去停止比較妥當啦。所以還是來個例子,以上面的例子來說,如果我中途要暫停某一個動態效果,那麼我必須要這麼做:

// 我們用一個 click 來停止他
$('stop-button').click(function() {
    $('#div-a').stop();
});

這樣,動態效果就會停止了。但是,你有發現什麼問題嗎?那就是,你要重新使用他的時候,就得重新在呼叫一次 myAnimate(); 這個程序。

// 我們用一個 click 來啟動他
$('start-button').click(function() {
    myAnimate();
});

看出問題了嗎?如果沒有 clearQueue 的話,你重新啟動他的時候,他並不會接著之前暫停的地方去執行,而是直接跳過上一個 queue,直接執行下一個 queue 內容!這樣知道差別了嗎?所以,我們需要做這樣的修改:

// 我們用一個 click 來停止他,並且清除這次的 queue 執行
$('stop-button').click(function() {
    $('#div-a').clearQueue();
    $('#div-a').stop();
});

這樣一來,如果我們重新呼叫 myAnimate(); 重新啟動的時候,就會從上次的結果繼續下去。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言